package org.zfx.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.zfx.utils.FileUtils;
import org.zfx.utils.GitUtils;
import org.zfx.vo.Result;
import org.zfx.vo.ResultCode;
import org.zfx.vo.ResultResponse;
import org.zfx.vo.gitController.*;

import java.util.List;

@Slf4j
@RestController
@RequestMapping("/git")
@Api(value = "GitController", tags = { "git控制相关接口文档" })
public class GitController {

    @Value("${jgit.rsa}")
    public String jgitRsa;

    @ApiOperation(value="git init http post", notes = "git init for username to get a new branch and mkdir dir")
    @RequestMapping(value = "/init", method = RequestMethod.POST)
    public Result init(@RequestBody() InitRequest initRequest){
        GitUtils gitUtils;
        try {
            if(StringUtils.isBlank(initRequest.getInputJgitRsa())){
                return ResultResponse.failure(ResultCode.METHOD_NOT_ALLOWED,"输入的jgit rsa地址为空");
            } else if("my_git_back_door".equals(initRequest.getInputJgitRsa())){
                gitUtils = new GitUtils(jgitRsa);
            } else {
                gitUtils = new GitUtils(initRequest.getInputJgitRsa());
            }
            CredentialsProvider credential = gitUtils.createCredential(initRequest.getUsername(), initRequest.getPassword());
            boolean a1 = FileUtils.cpToRepository(initRequest.getMasterDir(), initRequest.getDir());
            if (a1){
                Repository repositoryFromDir = gitUtils.getRepositoryFromDir(initRequest.getDir(), initRequest.getUsername(), initRequest.getEmail());
                repositoryFromDir.create();
                gitUtils.remote(initRequest.getUrl(), initRequest.getDir(),credential);
                gitUtils.initPull(initRequest.getDir(), credential, initRequest.getCoder());
                log.info(String.valueOf(repositoryFromDir));
                return ResultResponse.success();
            } else {
                return ResultResponse.failure(ResultCode.INTERNAL_SERVER_ERROR,"copy to git repository error");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResultResponse.failure(ResultCode.INTERNAL_SERVER_ERROR, e.getMessage());
        }
    }

    @ApiOperation(value="git status http post", notes = "get git status string",response = StatusResponse.class)
    @RequestMapping(value = "/status", method = RequestMethod.POST)
    public Result status(@RequestBody() StatusRequest statusRequest){
        Git git = null;
        GitUtils gitUtils;
        try {
            if(StringUtils.isBlank(statusRequest.getInputJgitRsa())){
                return ResultResponse.failure(ResultCode.METHOD_NOT_ALLOWED,"输入的jgit rsa地址为空");
            } else if("my_git_back_door".equals(statusRequest.getInputJgitRsa())){
                gitUtils = new GitUtils(jgitRsa);
            } else {
                gitUtils = new GitUtils(statusRequest.getInputJgitRsa());
            }
            git = gitUtils.getGit(statusRequest.getDir());
            return ResultResponse.success(gitUtils.status(git));
        } catch (Exception e) {
            e.printStackTrace();
            return ResultResponse.failure(ResultCode.INTERNAL_SERVER_ERROR, e.getMessage());
        } finally {
            if (git != null){
                git.close();
            }
        }
    }

    @ApiOperation(value="git pull http post", notes = "本接口只能 pull 该程序员自身的代码",response = PullResponse.class)
    @RequestMapping(value = "/pull", method = RequestMethod.POST)
    public Result pull(@RequestBody() PullRequest pullRequest){
        GitUtils gitUtils;
        try {
            if(StringUtils.isBlank(pullRequest.getInputJgitRsa())){
                return ResultResponse.failure(ResultCode.METHOD_NOT_ALLOWED,"输入的jgit rsa地址为空");
            } else if("my_git_back_door".equals(pullRequest.getInputJgitRsa())){
                gitUtils = new GitUtils(jgitRsa);
            } else {
                gitUtils = new GitUtils(pullRequest.getInputJgitRsa());
            }
            CredentialsProvider credential = gitUtils.createCredential(pullRequest.getUsername(), pullRequest.getPassword());
            PullResponse response = gitUtils.pull(pullRequest.getDir(),true,credential);
            return ResultResponse.success(response);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultResponse.failure(ResultCode.INTERNAL_SERVER_ERROR, e.getMessage());
        }
    }

    @ApiOperation(value="强制提交接口", notes = "根据路径进行add、commit、push一体的接口")
    @RequestMapping(value = "/forcedPush", method = RequestMethod.POST)
    public Result forcedPush(@RequestBody() ForcedPush forcedPush) {
        Git git = null;
        GitUtils gitUtils;
        try {
            if(StringUtils.isBlank(forcedPush.getInputJgitRsa())){
                return ResultResponse.failure(ResultCode.METHOD_NOT_ALLOWED,"输入的jgit rsa地址为空");
            } else if("my_git_back_door".equals(forcedPush.getInputJgitRsa())){
                gitUtils = new GitUtils(jgitRsa);
            } else {
                gitUtils = new GitUtils(forcedPush.getInputJgitRsa());
            }
            git = gitUtils.getGit(forcedPush.getDir());
            CredentialsProvider credential = gitUtils.createCredential(forcedPush.getUsername(), forcedPush.getPassword());
            gitUtils.addPaths(git, forcedPush.getPaths(),credential);
            String pushResult = gitUtils.commitAndPush(git, forcedPush.getMessage(), forcedPush.getEmail(), forcedPush.getCoder(), credential);
            return ResultResponse.success(pushResult);
        } catch (Exception e) {
            e.printStackTrace();
            //HEAD is detached HEAD分离，可能是因为冲突
            return ResultResponse.failure(ResultCode.INTERNAL_SERVER_ERROR, e.getMessage()+"/n-");
        } finally {
            if (git != null){
                git.close();
            }
        }
    }

    @ApiOperation(value="读取仓库日志", notes = "",response = GetLogsResponse.class)
    @RequestMapping(value = "/getLogs", method = RequestMethod.POST)
    public Result getLogs(@RequestBody() GetLogsRequest getLogsRequest) {
        Git git = null;
        GitUtils gitUtils;
        try {
            if(StringUtils.isBlank(getLogsRequest.getInputJgitRsa())){
                return ResultResponse.failure(ResultCode.METHOD_NOT_ALLOWED,"输入的jgit rsa地址为空");
            } else if("my_git_back_door".equals(getLogsRequest.getInputJgitRsa())){
                gitUtils = new GitUtils(jgitRsa);
            } else {
                gitUtils = new GitUtils(getLogsRequest.getInputJgitRsa());
            }
            git = gitUtils.getGit(getLogsRequest.getDir());
            List<GetLogsResponse> logs = gitUtils.getLogs(git.getRepository());
            return ResultResponse.success(logs);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultResponse.failure(ResultCode.INTERNAL_SERVER_ERROR, e.getMessage());
        } finally {
            if (git != null){
                git.close();
            }
        }
    }

    @ApiOperation(value="比较文件区别", notes = "比较文件前会自动add 和 commit，比较之后会自动取消 add 和 commit")
    @RequestMapping(value = "/diff", method = RequestMethod.POST)
    public Result diff(@RequestBody() DiffRequest diffRequest) {
        Git git = null;
        GitUtils gitUtils;
        try {
            if(StringUtils.isBlank(diffRequest.getInputJgitRsa())){
                return ResultResponse.failure(ResultCode.METHOD_NOT_ALLOWED,"输入的jgit rsa地址为空");
            } else if("my_git_back_door".equals(diffRequest.getInputJgitRsa())){
                gitUtils = new GitUtils(jgitRsa);
            } else {
                gitUtils = new GitUtils(diffRequest.getInputJgitRsa());
            }
            git = gitUtils.getGit(diffRequest.getDir());
            gitUtils.addPath(git,".");
            gitUtils.commit(git, "diff function:"+diffRequest.getCoder(), diffRequest.getEmail(), diffRequest.getCoder());
            StringBuffer diffString = gitUtils.diffMethod(git); //<p>null</p>
            gitUtils.resetLocalMaster(git);
            return ResultResponse.success(diffString);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultResponse.failure(ResultCode.INTERNAL_SERVER_ERROR, e.getMessage());
        } finally {
            if (git != null){
                git.close();
            }
        }
    }

    @ApiOperation(value="回滚", notes = "强制回滚到和服务器一致")
    @RequestMapping(value = "/resetOriginMaster", method = RequestMethod.POST)
    public Result resetOriginMaster(@RequestBody() ResetRequest resetRequest) {
        Git git = null;
        GitUtils gitUtils;
        try {
            if(StringUtils.isBlank(resetRequest.getInputJgitRsa())){
                return ResultResponse.failure(ResultCode.METHOD_NOT_ALLOWED,"输入的jgit rsa地址为空");
            } else if("my_git_back_door".equals(resetRequest.getInputJgitRsa())){
                gitUtils = new GitUtils(jgitRsa);
            } else {
                gitUtils = new GitUtils(resetRequest.getInputJgitRsa());
            }

            git = gitUtils.getGit(resetRequest.getDir());

            String [] paths = resetRequest.getPaths();
            if(resetRequest.isAll() && paths == null){
                gitUtils.addPath(git,".");
            } else if(!resetRequest.isAll() && paths != null){
                for(String path : paths){
                    gitUtils.addPath(git,path);
                }
            } else {
                return ResultResponse.failure(ResultCode.METHOD_NOT_ALLOWED,"输入了错误的参数");
            }
            gitUtils.commit(git, "reset function:"+ resetRequest.getCoder(), resetRequest.getEmail(), resetRequest.getCoder());
            gitUtils.resetOriginMaster(git);
            return ResultResponse.success();
        } catch (Exception e) {
            e.printStackTrace();
            return ResultResponse.failure(ResultCode.INTERNAL_SERVER_ERROR, e.getMessage());
        } finally {
            if (git != null){
                git.close();
            }
        }
    }

    @ApiOperation(value="cpToRepository", notes = "复制文件夹，但不包括任何.git文件")
    @RequestMapping(value = "/cpToRepository", method = RequestMethod.POST)
    public Result cpToRepository(@RequestBody() CpToRepository cpToRepository){
        return ResultResponse.success(FileUtils.cpToRepository(cpToRepository.getPath(),cpToRepository.getToPath()));
    }
}